<!-- components/Tooltip.vue -->
<template>
  <view class="tooltip-wrapper" ref="wrapper">
    <!-- 触发元素 -->
    <view 
      class="tooltip-target"
      @click="handleClick"
      @touchstart="handleTouchStart"
      @touchend="handleTouchEnd"
      @mouseenter="handleMouseEnter"
      @mouseleave="handleMouseLeave"
    >
      <slot></slot>
    </view>

    <!-- 遮罩层（仅点击触发且内容打开时显示） -->
    <view 
      v-if="visible && trigger === 'click'" 
      class="tooltip-mask" 
      @click="hide"
    ></view>
    
    <!-- Tooltip内容 -->
    <transition :name="transitionName">
      <view 
        v-if="visible" 
        class="tooltip-content"
        :class="[positionClass, { 'has-arrow': showArrow }]"
        :style="computedStyles"
        ref="tooltip"
        @click.stop="doNothing"
      >
        <view v-if="showArrow" class="tooltip-arrow"></view>
        <view class="tooltip-inner">
          <slot name="content">
            <text class="default-content">{{ content }}</text>
          </slot>
        </view>
      </view>
    </transition>
  </view>
</template>

<script>
import { ref, computed, watch, onUnmounted } from 'vue';

export default {
  name: 'Tooltip',
  props: {
    content: { type: String, default: '' },
    position: { type: String, default: 'top', validator: v => ['top','top-left','top-right','bottom','bottom-left','bottom-right','left','right'].includes(v) },
    trigger: { type: String, default: 'hover', validator: v => ['hover','click','manual'].includes(v) },
    showArrow: { type: Boolean, default: true },
    animation: { type: String, default: 'fade', validator: v => ['fade','slide'].includes(v) },
    visible: { type: Boolean, default: undefined },
    delay: { type: Number, default: 100 },
    maxWidth: { type: [Number, String], default: 488 }
  },
  emits: ['update:visible', 'show', 'hide'],
  setup(props, { emit }) {
    const visible = ref(false);
    const tooltip = ref(null);
    const wrapper = ref(null);
    const timeout = ref(null);

    const positionClass = computed(() => `tooltip-${props.position.replace('-', '')}`);
    const transitionName = computed(() => `tooltip-${props.animation}`);
    const computedStyles = computed(() => {
      const styles = {};
      if (props.maxWidth) {
        styles.maxWidth = typeof props.maxWidth === 'number' ? `${props.maxWidth}rpx` : props.maxWidth;
        styles.width = typeof props.maxWidth === 'number' ? `${props.maxWidth}rpx` : props.maxWidth;
      }
      return styles;
    });

    watch(() => props.visible, (newVal) => {
      if (newVal !== undefined) visible.value = newVal;
    }, { immediate: true });

    const show = () => {
      clearTimeout(timeout.value);
      if (props.delay > 0) {
        timeout.value = setTimeout(() => doShow(), props.delay);
      } else {
        doShow();
      }
    };
    const doShow = () => {
      if (visible.value) return;
      visible.value = true;
      emit('update:visible', true);
      emit('show');
    };
    const hide = () => {
      clearTimeout(timeout.value);
      if (props.delay > 0) {
        timeout.value = setTimeout(() => doHide(), props.delay);
      } else {
        doHide();
      }
    };
    const doHide = () => {
      if (!visible.value) return;
      visible.value = false;
      emit('update:visible', false);
      emit('hide');
    };

    const handleClick = () => {
      if (props.trigger !== 'click') return;
      if (visible.value) {
        hide();
      } else {
        show();
      }
    };
    const handleTouchStart = () => { if (props.trigger !== 'hover') return; show(); };
    const handleTouchEnd = () => { if (props.trigger !== 'hover') return; hide(); };
    const handleMouseEnter = () => { if (props.trigger !== 'hover') return; show(); };
    const handleMouseLeave = () => { if (props.trigger !== 'hover') return; hide(); };

    const doNothing = (e) => { e.stopPropagation(); };

    onUnmounted(() => { hide(); });

    return {
      visible,
      tooltip,
      wrapper,
      positionClass,
      transitionName,
      computedStyles,
      handleClick,
      handleTouchStart,
      handleTouchEnd,
      handleMouseEnter,
      handleMouseLeave,
      doNothing,
      hide
    };
  }
};
</script>

<style lang="scss" scoped>
.tooltip-wrapper {
  position: relative;
  display: flex;
}

.tooltip-target {
  display: flex;
}

.tooltip-content {
  position: absolute;
  z-index: 9999;
  min-width: 200rpx;
  padding: 16rpx 40rpx;
  border-radius: 16rpx;
  background-color: rgba(0, 0, 0, 0.8);
  color: #fff;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
  font-size: 32rpx;
  line-height: 1.5;
  
  &.has-arrow {
    margin: 14rpx 0;
  }
}

.tooltip-inner {
  position: relative;
  z-index: 2;
}

.default-content {
  color: inherit;
}

.tooltip-arrow {
  position: absolute;
  width: 16rpx;
  height: 16rpx;
  background: #333;
  transform: rotate(45deg);
  z-index: 1;
}

/* 遮罩层样式 */
.tooltip-mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0); /* 透明遮罩 */
  z-index: 9998; /* 确保遮罩层在弹层下方 */
}

/* 位置样式 */
.tooltip-top {
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  
  .tooltip-arrow {
    bottom: -8rpx;
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
  }
}

.tooltip-topleft {
  bottom: 100%;
  left: 0;
  
  .tooltip-arrow {
    bottom: -8px;
    left: 24px;
    transform: rotate(45deg);
  }
}

.tooltip-topright {
  bottom: 100%;
  right: 0;
  
  .tooltip-arrow {
    bottom: -8rpx;
    right: 24rpx;
    transform: rotate(45deg);
  }
}

.tooltip-bottom {
  top: 100%;
  left: 50%;
  transform: translateX(calc(-50% + 7rpx));
  
  .tooltip-arrow {
    top: -8rpx;
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
  }
}

.tooltip-bottomleft {
  top: 100%;
  left: 0;
  
  .tooltip-arrow {
    top: -8rpx;
    left: 24rpx;
    transform: rotate(45deg);
  }
}

.tooltip-bottomright {
  top: 100%;
  right: 0;
  
  .tooltip-arrow {
    top: -8rpx;
    right: 24rpx;
    transform: rotate(45deg);
  }
}

.tooltip-left {
  top: 50%;
  right: 100%;
  transform: translateY(-50%);
  
  .tooltip-arrow {
    top: 50%;
    right: -8rpx;
    transform: translateY(-50%) rotate(45deg);
  }
}

.tooltip-right {
  top: 50%;
  left: 100%;
  transform: translateY(-50%);
  
  .tooltip-arrow {
    top: 50%;
    left: -8rpx;
    transform: translateY(-50%) rotate(45deg);
  }
}

/* 动画效果 */
.tooltip-fade-enter-active,
.tooltip-fade-leave-active {
  transition: opacity 0.3s ease;
}

.tooltip-fade-enter-from,
.tooltip-fade-leave-to {
  opacity: 0;
}

.tooltip-slide-enter-active {
  transition: all 0.3s ease;
}

.tooltip-slide-leave-active {
  transition: all 0.2s ease;
}

.tooltip-slide-enter-from,
.tooltip-slide-leave-to {
  opacity: 0;
  transform: translateY(10px);
}

.tooltip-slide-enter-to {
  transform: translateY(0);
}

/* 针对不同位置的滑动动画调整 */
.tooltip-top.tooltip-slide-enter-from,
.tooltip-top.tooltip-slide-leave-to {
  transform: translateX(-50%) translateY(10px);
}

.tooltip-top.tooltip-slide-enter-to {
  transform: translateX(-50%) translateY(0);
}

.tooltip-bottom.tooltip-slide-enter-from,
.tooltip-bottom.tooltip-slide-leave-to {
  transform: translateX(-50%) translateY(-10px);
}

.tooltip-bottom.tooltip-slide-enter-to {
  transform: translateX(-50%) translateY(0);
}

.tooltip-left.tooltip-slide-enter-from,
.tooltip-left.tooltip-slide-leave-to {
  transform: translateY(-50%) translateX(10px);
}

.tooltip-left.tooltip-slide-enter-to {
  transform: translateY(-50%) translateX(0);
}

.tooltip-right.tooltip-slide-enter-from,
.tooltip-right.tooltip-slide-leave-to {
  transform: translateY(-50%) translateX(-10px);
}

.tooltip-right.tooltip-slide-enter-to {
  transform: translateY(-50%) translateX(0);
}
</style>
